package dongdongshop.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.dongdongshop.front.pojo.TbSeckillGoods;
import com.dongdongshop.front.pojo.TbSeckillGoodsExample;
import com.dongdongshop.front.pojo.TbSeckillOrder;
import com.dongdongshop.front.service.SeckillGoodsService;
import dongdongshop.mapper.TbSeckillGoodsMapper;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Component
public class SeckillGoodsServiceImpl implements SeckillGoodsService  {

    @Resource
    private TbSeckillGoodsMapper seckillGoodsMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public List<TbSeckillGoods> getSeckillGoods() {
        //获取所有值
        List<TbSeckillGoods> seckillGoodsRedis = redisTemplate.boundHashOps("seckillGoods").values();
        if (seckillGoodsRedis == null || seckillGoodsRedis.size() <= 0){
            //redis缓存中没有就查询数据库
            TbSeckillGoodsExample example = new TbSeckillGoodsExample();
            TbSeckillGoodsExample.Criteria criteria = example.createCriteria();
            //查询审核通过的 1 表示通过
            criteria.andStatusEqualTo("1");
            //查询规定时间内的
            criteria.andStartTimeLessThanOrEqualTo(new Date());//开始时间《=当前时间
            criteria.andEndTimeGreaterThanOrEqualTo(new Date());//结束时间 》= 当前时间
            //库存大于0 的
            criteria.andStockCountGreaterThan(0);
            seckillGoodsRedis = seckillGoodsMapper.selectByExample(example);

          /*  for (TbSeckillGoods seckillGoods : seckillGoodsRedis) {
                //将查询的数据放入redis缓存
                redisTemplate.boundHashOps("seckillGoods").put(seckillGoods.getId(),seckillGoods);
                //吧每一个商品的库存放到redis里
                redisTemplate.boundHashOps("seckillGoodsStockCount").put(seckillGoods.getId(),seckillGoods.getStockCount());
            }*/

            seckillGoodsRedis.stream().forEach(
                    x -> {
                        //将查询的数据放入redis缓存
                        redisTemplate.boundHashOps("seckillGoods").put(x.getId(),x);
                        //吧每一个商品的库存放到redis里
                        redisTemplate.boundHashOps("seckillGoodsStockCount").put(x.getId(),x.getStockCount());
                    }
            );


        }
        return seckillGoodsRedis;
    }

    @Override
    public TbSeckillGoods getSeckillById(Long id) {
        TbSeckillGoods seckillGoods = (TbSeckillGoods) redisTemplate.boundHashOps("seckillGoods").get(id);
        return seckillGoods;
    }

    //秒杀，抢购
    @Override
    public void submitorder(Long seckillId, String username) {
        //从缓存中取出商品
        TbSeckillGoods seckillGoods = (TbSeckillGoods) redisTemplate.boundHashOps("seckillGoods").get(seckillId);
        //如果不存在这件商品
        if(seckillGoods == null){
            throw new RuntimeException("商品不存在!");
        }
        //如果商品存在，但是没有库存
        if (seckillGoods.getStockCount() <= 0){
            throw new RuntimeException("商品不被抢光了！请关注下次活动！");
        }
        //一个用户只能购买一次
        if (redisTemplate.hasKey("seckillGoodsOnlyOne"+username+seckillId)){
            throw new RuntimeException("同一个商品只能抢购一次哦！");
        }
        //减库存
        seckillGoods.setStockCount(seckillGoods.getStockCount()-1);
        //将商品再放入缓存
        redisTemplate.boundHashOps("seckillGoods").put(seckillId,seckillGoods);
        //如果商品再次交易中卖光，更新数据库
        if (seckillGoods.getStockCount() == 0){
            //同步到数据库
            seckillGoodsMapper.updateByPrimaryKeySelective(seckillGoods);
            //把缓存中的数据删除
            redisTemplate.boundHashOps("seckillGoods").delete(seckillId);
        }
        //异步生成订单
        Map<String,Object> map = new HashMap<>();
        map.put("seckillId",seckillId);
        map.put("username",username);
        rocketMQTemplate.convertAndSend("SECKILLGOODS",map);
        System.out.println("秒杀抢购mq发送成功");

    }

    @Override
    public TbSeckillOrder findOrder(Long seckillId, String username) {
        return (TbSeckillOrder)redisTemplate.boundHashOps("seckillOrder").get(username+""+seckillId);
    }
}
